home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 026-050 / scopedisk45 / ruler3 / ruler3.c < prev    next >
C/C++ Source or Header  |  1995-03-18  |  10KB  |  387 lines

  1. /*    RULER
  2.  *
  3.  *    Opens a borderless WorkBench window in which is contained a ruler for
  4.  *    the purpose of aligning or constraining text; the default ruler is 30
  5.  *    characters intended to help prevent entering too-long filenames.
  6.  *
  7.  *    Usage:
  8.  *
  9.  *    CLI> RUN  RULER  [ size ] [ scale ]
  10.  *
  11.  *    where `size' must be between 12 and your maximum screen columns
  12.  *    inclusive and defaults to 30, and `scale' is the size of the font to
  13.  *    enter, and is limited depending on the size of your screen.
  14.  *
  15.  *    The window, of course, can be moved to any convenient location on the
  16.  *    screen, and resized with an invisible resizing gadget found in the
  17.  *    lower right corner.
  18.  *
  19.  *    Version 3.0   06-Dec-1988  (c)1988 Chad Netzer and Thad Floryan
  20.  *
  21.  *        Based upon code, idea, and logic from:
  22.  *
  23.  *    Version 1.0   7-Nov-1988   (c)1988 Thad Floryan
  24.  *
  25.  *    Revision history:
  26.  *        06-Dec-1988 - (Ver. 3.0) - Added support for measuring fonts of
  27.  *        varying widths (selectable scale).
  28.  *
  29.  *        22-Nov-1988 - (Ver. 2.2) - More adjustments to code, No major
  30.  *            changes.  Program size is slightly smaller.  (CFN)
  31.  *
  32.  *        14-Nov-1988 - (Ver. 2.1) - Fixed a few minor (harmless) bugs.  The
  33.  *        right edge of the ruler is now always redrawn after resizing.
  34.  *        I got rid of that GOTO statement (which in 'C', is considered a
  35.  *        bug. :-)  Version 2.1 now lets you open a ruler to be as low as
  36.  *        12 characters wide, which 2.0 only advertised. (CFN)
  37.  *
  38.  *        13-Nov-1988 - (Ver. 2.0) - I added minor enhancements, most
  39.  *        noteably, the ability to resize the window, and support for 
  40.  *        overscanned screens.    (CFN)
  41.  *
  42.  *
  43.  *    Feel welcome to use this program for any non-commercial purposes or
  44.  *    for your personal learning.  Commercial users are requested to contact
  45.  *    Thad at either:
  46.  *
  47.  *    UUCP:    thad@cup.portal.com (OR) ..!sun!portal!cup.portal.com!thad
  48.  *    BBS:    BBS-JC, 415/961-7250 (300/1200/2400), "Thad Floryan" | "SYSOP"
  49.  *
  50.  *    Building instructions (Manx Aztec C):
  51.  *
  52.  *        cc ruler
  53.  *        ln ruler -lc
  54.  */
  55.  
  56. #include <exec/types.h>
  57. #include <intuition/intuition.h>
  58. #include <intuition/intuitionbase.h>
  59.  
  60. #define NEW(typ)        AllocMem((ULONG)sizeof(typ),MEMF_CLEAR)
  61. #define FREE(p,typ)        FreeMem(p,(ULONG)sizeof(typ))
  62.  
  63. #define    ever (;;)    /* used for infinite loops */
  64.  
  65. #define FATAL 20    /* exit code */
  66. #define WARN  10    /* exit code */
  67. #define NORMAL 0    /* exit code */
  68.  
  69. extern void    *OpenLibrary();
  70. extern void    *OpenWindow();
  71. extern void    *GetMsg();
  72. extern void    *AllocMem();
  73. extern void    ReplyMsg();
  74. extern long    atol();
  75. void        release_resources();
  76. void        error_exit();
  77.  
  78. struct NewWindow window_def =
  79. {
  80.     240, 0,            /* Initial LeftEdge, TopEdge */
  81.     241, 25,        /* Default pixel-width, pixel-height */
  82.     0, 1,            /* DetailPen, BlockPen */
  83.     CLOSEWINDOW    |    /* IDCMP flags */
  84.     NEWSIZE,
  85.     WINDOWDRAG    |    /* window flags */
  86.     WINDOWDEPTH    |
  87.     WINDOWCLOSE    |
  88.     WINDOWSIZING    |
  89.     SMART_REFRESH    |
  90.     NOCAREREFRESH    |
  91.     BORDERLESS    |
  92.     RMBTRAP,
  93.     NULL,            /* Gadget list */
  94.     NULL,            /* checkmark stuff */
  95.     (UBYTE *)"",        /* window title (to be filled in later) */
  96.     NULL,            /* custom screen pointer */
  97.     NULL,            /* bitmap pointer */
  98.     97, 0,            /* no Minwidth, MinHeight */
  99.     -1, 0,            /* no MaxWidth, MaxHeight */
  100.     WBENCHSCREEN        /* screen type */
  101. };
  102.  
  103. struct Window        *window;
  104. struct RastPort     *rp;
  105. struct IntuitionBase    *IntuitionBase;
  106. struct GfxBase        *GfxBase;
  107. struct Screen        *screen;
  108. struct IntuiMessage    *sys_message;
  109. ULONG            class;
  110. int            resource_state;
  111.  
  112. char *version = 
  113.     "Text Ruler   V3.0   06-Dec-88 \xA91988 Thad Floryan and Chad Netzer"
  114.     "                                 "; /* padding for "nice" title */
  115.  
  116. /**********************************************************************/
  117.  
  118. main (argc, argv)
  119.     int    argc;
  120.     char    *argv[];
  121. {
  122.  
  123.     long    fivec;        /* pixel size of five chars    */
  124.     long    fsize;        /* The font size of ruler scale */
  125.     long    max_scale;    /* The max scale size possible  */
  126.     long    max_width;    /* maximum width of window    */
  127.     long    w;        /* character width of ruler    */
  128.     long    w_lim;        /* pixel width per w * 8    */
  129.     long    x;        /* present window x coordinate    */
  130.     long    y;        /* present window y coordinate    */
  131.     char    buf[5];
  132.  
  133.     long    success;    /* indicates bad return values    */
  134.  
  135.     resource_state = 0;
  136.  
  137. /*
  138.  *    Open Intuition so we can get the screen size limits.
  139.  */
  140.     IntuitionBase = OpenLibrary ("intuition.library", 0L);
  141.     if (IntuitionBase == 0L)
  142.     {
  143.         error_exit("?Cannot open intuition.library\n");
  144.     }
  145.     ++resource_state;
  146.  
  147. /*
  148.  *    Get WorkBench screen information
  149.  */
  150.     screen = NEW(struct Screen);    /* Allocate a buffer for screen data */
  151.     if (screen == 0L)
  152.     {
  153.         release_resources();
  154.         error_exit("?ran out of available memory\n");
  155.     }
  156.     ++resource_state;
  157.     success = GetScreenData(screen, (ULONG) sizeof (struct Screen), 
  158.                 WBENCHSCREEN, 0L);
  159.     if (success == FALSE)
  160.     {
  161.         error_exit();
  162.     }
  163. /*
  164.  *    Set up defaults...
  165.  */
  166.     w = 30L;    /* default ruler is 30 chars for a filename */
  167.     fsize = 8L;    /* default font scale is 8 pixels per char  */
  168.  
  169. /*
  170.  *    Parse command line to obtain requested parameters.
  171.  */
  172.     if (argc > 3)
  173.     {
  174.         printf("?Too many arguments, ``%s ?'' for help\n", argv[0]);
  175.         release_resources();
  176.         exit (WARN);
  177.     }
  178.     if (argc == 3)
  179.     { 
  180.         fsize = atoi(argv[2]);
  181.     }
  182.  
  183. /*
  184.  *    find maximum width in pixels, and convert to characters.
  185.  */
  186.     max_width = screen->Width;
  187.     max_scale = (screen->Width - 2) / 12;
  188.     if (fsize > max_scale)
  189.     {
  190.         printf("?Font size can be NO larger than %ld!", max_scale);
  191.         release_resources();
  192.         exit (WARN);
  193.     }
  194.     max_width /= fsize;
  195.     if (argc == 2)
  196.     {
  197.         if (*argv[1] == '?' ||
  198.         *argv[1] == '-' ||
  199.         *argv[1] == 'h' ||
  200.         *argv[1] == 'H'   )
  201.         {
  202.         printf( "%40s\n"
  203.             "Opens a borderless WorkBench window in which is "
  204.             "contained a ruler for the\npurpose of aligning or "
  205.             "constraining text; the default ruler is 30 "
  206.             "characters\nof an 8 pixel scale intended to help "
  207.             "prevent entering too-long filenames.\n           "
  208.             "Usage:\n\n\t"
  209.             "CLI> RUN  %s  [ size ] [ scale ]\n\nwhere `size'"
  210.             "must be between 12 and %ld inclusive, at 8 pixel"
  211.             "scale, and defaults\nto 30, and `scale' is the size "
  212.             "of the font to measure, in pixels, and must\nbe less "
  213.             "than %ld.\n", version, argv[0], max_width, max_scale);
  214.         release_resources();
  215.         exit (NORMAL);
  216.         }
  217.         else
  218.         {
  219.         w = atol(argv[1]);
  220.         if ( w < 12L  ||  w > max_width )
  221.         {
  222.             printf("?Value must be >= 12 and <= %ld\n", max_width);
  223.             release_resources();
  224.             exit (WARN);
  225.         }
  226.         }
  227.     }
  228. /*
  229.  *    Now calculate window sizing and placement parameters and setup title.
  230.  */
  231.     w_lim               = w * fsize;
  232.     window_def.Width    = w_lim + 1;
  233.     window_def.LeftEdge = (window_def.Width > 300L) ? 0 : 240;
  234.     window_def.Title    = (UBYTE *)version;
  235.     fivec            = 5L * fsize;
  236. /*
  237.  *    Bomb out if requested ruler size would be larger than the screen.
  238.  */
  239.     if (window_def.Width > screen -> Width )
  240.     {
  241.         error_exit("?Ruler too large for WorkBench screen\n");
  242.     }
  243. /*
  244.  *    Open up the graphics library.
  245.  */
  246.     GfxBase = OpenLibrary ("graphics.library", 0L);
  247.     if (GfxBase == 0L)
  248.     {
  249.         error_exit("?Cannot open graphics.library\n");
  250.     }
  251.     ++resource_state;
  252. /*
  253.  *    Open the ruler display window.
  254.  */
  255.     window = OpenWindow (&window_def);
  256.     if (window == 0L)
  257.     {
  258.         error_exit("?Cannot open window\n");
  259.     }
  260.     ++resource_state;
  261. /*
  262.  *    Get pointer to raster port.
  263.  */
  264.     rp = window -> RPort;
  265.     SetAPen (rp, 0L);
  266. /*
  267.  *    Use RectFill to blank the window area and set pen for drawing.
  268.  */
  269.     for ever
  270.         {
  271.         SetAPen (rp, 0L);
  272.          RectFill (rp, 0L, 10L, w_lim, 24L);
  273. /*
  274.  *    Now set pen to draw.
  275.  */
  276.         SetAPen (rp, 1L);
  277. /*
  278.  *    Because we've used a BORDERLESS window, must fill in some of the
  279.  *    title-/drag-bar space near the lower left where the text starts.
  280.  */
  281.         Move(rp, 28L, 8L);
  282.         Draw(rp, 31L, 8L);
  283. /*
  284.  *    Because we've used a BORDERLESS window, must draw our own line beneath
  285.  *    the title bar to make the bar the same height as the window gadgets.
  286.  *    The `28' is the pixel position just to the right of the close gadget.
  287.  *    The `53' is the pixel width of the depth-arranging gadgets in the upper
  288.  *    right corner of the window.
  289.  */
  290.         Move(rp, 28L,           9L);
  291.         Draw(rp, (w_lim - 53L), 9L);
  292. /*
  293.  *    Draw ruler and text
  294.  */
  295.         for (x = 0L; x < (w_lim + fsize); x += fsize)
  296.         {
  297.         if (x >= w_lim)        /* right edge         */
  298.             {
  299.             x = w_lim;
  300.             y = 10L;
  301.             }
  302.         else if (x == 0L)       y = 10L;    /* left edge         */
  303.         else if ((x % fivec) == 0L)  y = 19L;    /* big tic every 5 chars */
  304.         else                       y = 22L;    /* small tic every char  */
  305.         Move (rp, x, y);
  306.         Draw (rp, x, 24L);
  307. /*
  308.  *    Label ruler.
  309.  *    The test for position 40 (in the Move()) is for centering ``5''
  310.  *    differently than the centering for two-digit numbers.
  311.  */
  312.         if ((x > 0L) && (x < w_lim) && ((x % fivec) == 0L))
  313.         {
  314.             sprintf (buf, "%2ld", (x / fsize));
  315.             Move (rp, (x == fivec) ? (x - 12L) : (x - 8L), 17L);
  316.             Text (rp, buf, (long) strlen (buf));
  317.         }
  318.         }
  319. /*
  320.  *    Wait for gadget activation.  No busy-/spin-/wait-loops here!
  321.  */
  322.         Wait (1L << window -> UserPort -> mp_SigBit);
  323. /*
  324.  *    Retrieve LAST message in Message Port
  325.  */
  326.         sys_message = GetMsg(window -> UserPort);
  327.         class = sys_message -> Class;
  328.         ReplyMsg(sys_message);
  329. /*
  330.  *    Dump uneeded messages (respond only to the last on LIFO queue).
  331.  */
  332.         while (sys_message = GetMsg(window -> UserPort))
  333.         {
  334.         ReplyMsg(sys_message);
  335.         }
  336.  
  337.         if (class == CLOSEWINDOW)
  338.         {
  339.         release_resources();
  340.         exit (NORMAL);
  341.         }
  342.  
  343.         if (class == NEWSIZE)
  344.         {
  345.         w_lim = (window -> Width) - 1;
  346.         }
  347.     }
  348. }
  349.  
  350. /**********************************************************************
  351.  *
  352.  *    cleanup routine
  353.  *
  354.  *    The ``switch'' on resource_state is to assure we don't attempt to
  355.  *    free something we don't have.  Items are released in the reverse
  356.  *    order they were obtained (by "falling thru" the cases).
  357.  */
  358. void release_resources()
  359. {
  360.     switch (resource_state)
  361.     {
  362.         case 4: CloseWindow (window);
  363.         case 3: CloseLibrary(GfxBase);
  364.         case 2: FREE (screen, struct Screen);
  365.         case 1: CloseLibrary(IntuitionBase);
  366.     }
  367. }
  368.  
  369. /**********************************************************************
  370.  *
  371.  *    error handler
  372.  */
  373. void error_exit(message)
  374.     char    *message;
  375. {
  376.     if (message == 0L)
  377.     {
  378.         printf("Internal failure, exiting gracefully...\n");
  379.     }
  380.     else
  381.     {
  382.         printf(message);
  383.     }
  384.     release_resources();
  385.     exit (FATAL);
  386. }
  387.